package com.miyake.loveviewweb.client.viewer;

import java.util.List;

import com.google.appengine.api.datastore.Key;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.miyake.loveviewweb.client.DataServiceWrapper;
import com.miyake.loveviewweb.client.viewer.table.DataWidget;
import com.miyake.loveviewweb.shared.model.DataModel;
import com.miyake.loveviewweb.shared.model.ImageDataBodyModel;
import com.miyake.loveviewweb.shared.model.PluginModel;
import com.miyake.loveviewweb.shared.model.ValueModel;

public class DataSummaryWidget extends Composite {
    private VerticalPanel panel = new VerticalPanel();
    private int level = 2;
    
    public DataSummaryWidget(Key dataKey) {
        initWidget(panel);
        
        DataServiceWrapper.getInstance().getService().getData(dataKey, false, new AsyncCallback<DataModel>() {
            public void onFailure(Throwable caught) {
            }

            public void onSuccess(DataModel result) {
                initialize(result);  
            }
        });
    }
    
    public DataSummaryWidget(DataModel dataModel) {
        this.level = 2;
        initWidget(panel);       
        initialize(dataModel);
    }
    
    public DataSummaryWidget(DataModel dataModel, int level) {
        this.level = level;
        initWidget(panel);       
        initialize(dataModel);
    }
    
    private void initialize(final DataModel dataModel) {
        panel.setWidth("100%");
        // Title
        if (level > 2 ) {
            //String slevel = String.valueOf(level+2);
            //panel.add(new HTML("<h" + slevel + ">"+ dataModel.getName() + "</h" + slevel + ">"));
            panel.add(new HTML("<b>" + dataModel.getName() + "</b>"));
        }
        
        // Properties
        panel.add(getPropertyTable(dataModel));
        
        if (isValueVisible(dataModel)) {
            // Values
            panel.add(getValueTable(dataModel));
        }

        if (isXyData(dataModel)) {
            if (isDataVisible(dataModel)) {
                panel.add(new DataWidget(dataModel));
            }
        }
        else if (isImage(dataModel)){
            final Image image = new Image();
            final ImageDataBodyModel imageDataBody = dataModel.getImageDataBody();
            image.setUrl(imageDataBody.getUrl());
            
            image.addLoadHandler(new LoadHandler() {
                public void onLoad(LoadEvent event) {
                    if (imageDataBody.isOriginalSizeUknown()) {
                        imageDataBody.setOriginalWidth( image.getWidth() );
                        imageDataBody.setOriginalHeight( image.getHeight() );
                    }
                }
            });
            
            ImageToolbar imageToolbar = new ImageToolbar() {
                @Override
                protected void onSizeOriginal() {
                    image.setSize(imageDataBody.getOriginalWidth() + "px", imageDataBody.getOriginalHeight() + "px");
                    imageDataBody.setWidth(image.getWidth());
                    imageDataBody.setHeight(image.getHeight());
                    updateImage(imageDataBody);
                }

                @Override
                protected void onSizeChange(String width, String height) {
                    image.setSize(width, height);
                    imageDataBody.setWidth(image.getWidth());
                    imageDataBody.setHeight(image.getHeight());
                    updateImage(imageDataBody);
                }
            };
            panel.add(imageToolbar);
            panel.add(image);
            if (imageDataBody.isSizeFixed()) {
                image.setSize(imageDataBody.getWidth() + "px", imageDataBody.getHeight() + "px");
            }
        }
        // Sub data
        DataServiceWrapper.getInstance().getService().getSubDataList(dataModel.getKey(), false, new AsyncCallback<List<DataModel>>() {
            public void onFailure(Throwable caught) {
            }

            public void onSuccess(List<DataModel> result) {
                for (DataModel dm : result) {
                    panel.add(new DataSummaryWidget(dm, level+1));
                }
            }
            
        });
        
    }

    private boolean isImage(final DataModel dataModel) {
        return dataModel.getDataType().equals(DataModel.DataType.Image);
    }

    private boolean isXyData(final DataModel dataModel) {
        return dataModel.getDataType().equals(DataModel.DataType.ValueArray);
    }

    protected void updateImage(ImageDataBodyModel imageDataBody) {
        DataServiceWrapper.getInstance().getService().updateImageDataBodyModel(imageDataBody, new AsyncCallback<Void>() {
            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Void result) {

            }
        });
    }

    private boolean isDataVisible(DataModel dataModel) {
        if (dataModel.getXyDataBody() == null) {
            return false;
        }
        else if (dataModel.getXyDataBody().getDataColumn().size() > 0) {
            return true;
        }
        return false;
    }

    private boolean isValueVisible(final DataModel dataModel) {
        if (isNotParsed(dataModel) && dataModel.isParsed()) {
            return true;
        }
        if (dataModel.getSourceType().equals(DataModel.SourceType.Plugin)) {
            return true;
        }
        if (dataModel.getSourceType().equals(DataModel.SourceType.Manual)) {
            return true;
        }
        return false;
    }
    
    private Widget getPropertyTable(DataModel dataModel) {
        VerticalPanel panel = new VerticalPanel();
        HorizontalPanel subPanel = new HorizontalPanel();
        
        panel.add(subPanel);
        if (dataModel.getSourceType() !=  null) {
            subPanel.add(new HTML("Data Type:"));
            subPanel.add(new HTML(dataModel.getSourceType().toString()));
        }

        if (isParsedFile(dataModel)) {
            subPanel.add(new HTML("Parsed by :"));
            final HTML parser = new HTML();
            subPanel.add(parser);
            DataServiceWrapper.getInstance().getService().getPlugin(dataModel.getPlugin(), new AsyncCallback<PluginModel>() {
                public void onFailure(Throwable caught) {
                }

                public void onSuccess(PluginModel result) {
                    parser.setHTML(result.getServiceName());
                }
            });
            
        }
        else if (isNotParsed(dataModel)){
            Label label = new Label("This file has not been parsed!");
            label.setStylePrimaryName("alart");
            panel.add(label);
        }
        
        if (dataModel.getOriginalData() != null) {
            panel.add(new HTML("<A HREF=" + dataModel.getOriginalDataUrl() + ">" + "Download"/*dataModel.getName()*/ + "</A>"));
        }
        return panel;
    }

    private boolean isNotParsed(DataModel dataModel) {
        return dataModel.getSourceType().equals(DataModel.SourceType.File) && isXyData(dataModel);
    }

    private boolean isParsedFile(DataModel dataModel) {
        return dataModel.isParsed() && isNotParsed(dataModel);
    }

    private Widget getValueTable(DataModel dataModel) {
        CellTable<ValueModel> valueGrid = new CellTable<ValueModel>();
        valueGrid.addColumn(new TextColumn<ValueModel>() {
            @Override
            public String getValue(ValueModel object) {
                return object.getCaption();
            } 
        });
        valueGrid.addColumn(new TextColumn<ValueModel>() {
            @Override
            public String getValue(ValueModel object) {
                return object.getValue();
            } 
        });

        valueGrid.addColumn(new TextColumn<ValueModel>() {
            @Override
            public String getValue(ValueModel object) {
                return object.getSubUnit() + object.getUnit();
            } 
        });
        valueGrid.setRowData(dataModel.getValues());
        return valueGrid;
    }
    
}
